import {apiInvoke, queryInterfaceById, queryInvokeCountByPage} from '@/services/ant-design-pro/interfaceInfoController';
import { DownOutlined } from '@ant-design/icons';
import {EditableProTable, PageContainer, ProCard, ProColumns} from '@ant-design/pro-components';
import InterfaceInfoDrawer from '../../../components/Interface'
import {
  Col,
  Dropdown,
  Input,
  MenuProps,
  Row,
  Select,
  Space,
  Radio,
  Tabs,
  TabsProps,
  Tag,
  message, Divider,
} from 'antd';
import React, {useEffect, useState} from 'react';
import {TableRowSelection} from "antd/es/table/interface";

type DataSourceType = {
  key: React.Key;
  title?: string;
  description?: string;
  state?: string;
  created_at?: number;
  children?: DataSourceType[];
};

const defaultData: DataSourceType[] = new Array(3).fill(1).map((_, index) => {
  return {
    key: (Date.now() + index).toString(),
    title: `活动名称${index}`,
    description: '这个活动真好玩',
    state: 'open',
    created_at: 1590486176000,
  };
});


/**
 * 请求选项 todo做成配置式
 */
const requestMethodOptions = [
  {
    value: 'GET',
    label: (
      <Tag bordered={false} color="processing">
        GET
      </Tag>
    ),
  },
  {
    value: 'POST',
    label: (
      <Tag bordered={false} color="success">
        POST
      </Tag>
    ),
  },
  {
    value: 'PUT',
    label: (
      <Tag bordered={false} color="error">
        PUT
      </Tag>
    ),
  },
  {
    value: 'DELETE',
    label: (
      <Tag bordered={false} color="warning">
        DELETE
      </Tag>
    ),
  },
  {
    value: 'OPTIONS',
    label: (
      <Tag bordered={false} color="magenta">
        OPTIONS
      </Tag>
    ),
  },
  {
    value: 'PATCH',
    label: (
      <Tag bordered={false} color="orange">
        PATCH
      </Tag>
    ),
  },
];

const App: React.FC = () => {

  /**
   * 接口文档相关
   * ---------------------------------
   */
  const [openDrawer, setOpenDrawer] = useState(false);
  const [currentInterfaceDetail,setCurrentInterfaceDetail] = useState<API.InterfaceInfoVO>()
  const onMenuClick: MenuProps['onClick'] = async (e) => {

    const res = await queryInterfaceById({
      id:e.key
    })
    if (res?.code === 200){
      setCurrentInterfaceDetail({
        ...res.data
      })
      setOpenDrawer(true)
      return;
    }
    message.error(res?.message)
  };

  const [interfaceInfoList, setInterfaceInfoList] = useState<API.InterfaceInfoVO[]>();
  const listInterfaceInfo = (params: API.QueryCountRequest) => {
    queryInvokeCountByPage({
      type: "apply",
      ...params,
    }).then((res: any) => {
      if (res?.code === 200) {
        const records = res?.data?.records.map(item=>{
          return {
            key: item.id,
            label: item.name,
          }
        })
        setInterfaceInfoList([...records]);
        return;
      }
      message.error(res?.message);
    })
  };
  useEffect(() => {
    listInterfaceInfo({});
  }, []);


  /**
   * 发送请求相关
   */
  const [invokeParam, setInvokeParam] = useState<API.StarryApiRequest>({
    url:"http://192.168.47.1:9527/simulator/get",
    method:"GET",
    requestHeader:[],
    requestParam:[],
    requestBodyOption:{
      bodyType:"NONE",
      requestBodyType:"JSON",
      requestBody:""
    }
  });
  const [baseResponse,setBaseResponse] = useState<API.BaseResponseObject>()

  const sendRequest = async () => {
    console.log(invokeParam)
    const res = await apiInvoke({
      ...invokeParam,
    });
    if (res?.code === 200) {
      setBaseResponse(res?.data)
      message.success(res?.message);
      return;
    }
    message.error(res?.message);
  };

  /**
   * tab栏相关
   * @param key
   */
  const onTabChange = (key: string) => {
    console.log(key);
  };

  const [editableKeys, setEditableRowKeys] = useState<React.Key[]>(() =>
    defaultData.map((item) => item.key),
  );
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);

  const onSelectChange = (newSelectedRowKeys: React.Key[]) => {
    console.log('selectedRowKeys changed: ', newSelectedRowKeys);
    setSelectedRowKeys(newSelectedRowKeys);
  };

  const rowSelection: TableRowSelection<API.NameValueField> = {
    selectedRowKeys,
    onChange: onSelectChange,
  };

  const requestHeaderColumns: ProColumns<API.NameValueField>[] = [
    {
      title: '参数名',
      dataIndex: 'name',
      width: '30%',
    },
    {
      title: '参数值',
      key: 'value',
      dataIndex: 'value',
    },
    {
      title: '描述',
      dataIndex: 'description',
    },
    {
      title: '操作',
      valueType: 'option',
      width: 250,
      render: () => {
        return null;
      },
    },
  ];

  const requestParamColumns: ProColumns<API.NameValueField>[] = [
    {
      title: '参数名',
      dataIndex: 'name',
      width: '30%',
    },
    {
      title: '参数值',
      key: 'value',
      dataIndex: 'value',
    },
    {
      title: '描述',
      dataIndex: 'description',
    },
    {
      title: '操作',
      valueType: 'option',
      width: 250,
      render: () => {
        return null;
      },
    },
  ];

  const tabItems: TabsProps['items'] = [
    {
      key: '1',
      label: 'Header',
      children: (
        <EditableProTable<API.NameValueField>
          headerTitle={false}
          columns={requestHeaderColumns}
          rowKey="key"
          rowSelection={rowSelection}
          scroll={{
            x: 960,
          }}
          value={invokeParam?.requestHeader}
          onChange={(value) => {
            setInvokeParam({
              ...invokeParam,
              requestHeader: [...value],
            });
          }}
          recordCreatorProps={{
            newRecordType: 'dataSource',
            record: () => ({
              key: Date.now(),
              name:"",
              value:"",
              description:""
            }),
          }}
          editable={{
            type: 'multiple',
            editableKeys,
            actionRender: (row, config, defaultDoms) => {
              return [defaultDoms.delete];
            },
            onValuesChange: (record, recordList) => {
              setInvokeParam({
                ...invokeParam,
                requestHeader:[...recordList]
              });
            },
            onChange: setEditableRowKeys,
          }}
        />
      ),
    },
    {
      key: '2',
      label: 'Query',
      children: (
        <EditableProTable<API.NameValueField>
          // headerTitle="可编辑表格"
          columns={requestParamColumns}
          rowKey="key"
          scroll={{
            x: 960,
          }}
          value={invokeParam?.requestParam}
          onChange={(value) => {
            setInvokeParam({
              ...invokeParam,
              requestParam: [...value],
            });
          }}
          recordCreatorProps={{
            newRecordType: 'dataSource',
            record: () => ({
              key: Date.now(),
              name:"",
              value:"",
              description:""
            }),
          }}
          editable={{
            type: 'multiple',
            editableKeys,
            actionRender: (row, config, defaultDoms) => {
              return [defaultDoms.delete];
            },
            onValuesChange: (record, recordList) => {
              setInvokeParam({
                ...invokeParam,
                requestParam:[...recordList]
              });
            },
            onChange: setEditableRowKeys,
          }}
        />
      ),
    },
    {
      key: '3',
      label: 'Body',
      children: (<>
        <Radio.Group onChange={(e)=>{
          setInvokeParam({
            ...invokeParam,
            requestBodyOption: {
              requestBody: invokeParam?.requestBodyOption?.requestBody,
              requestBodyType: invokeParam?.requestBodyOption?.requestBodyType,
              bodyType:e.target.value
            }
          })
        }}
          value={invokeParam?.requestBodyOption?.bodyType}>
          <Radio value='NONE'>none</Radio>
          <Radio value='FORM_DATA'>form-data</Radio>
          <Radio value='URLENCODED'>urlendcoded</Radio>
          <Radio value='BINARY'>binary</Radio>
          <Radio value='RAW'>raw</Radio>
        </Radio.Group>
        {
          invokeParam?.requestBodyOption?.bodyType === 'RAW'
          &&
          (
            <Select
              defaultValue="JSON"
              style={{ width: 120 }}
              onChange={(value)=>setInvokeParam({
                ...invokeParam,
                requestBodyOption:{
                  requestBody: invokeParam?.requestBodyOption?.requestBody,
                  bodyType: invokeParam?.requestBodyOption?.bodyType,
                  requestBodyType: value
                }
              })}
              options={[
                { value: 'JSON', label: 'json' },
                { value: 'XML', label: 'xml' },
                { value: 'JAVASCRIPT', label: 'javascript' },
                { value: 'PLAIN', label: 'plain' },
                { value: 'HTML', label: 'html' },
              ]}
            />
          )
        }
        <Divider/>
        {
          invokeParam?.requestBodyOption?.bodyType === "RAW"
          &&
          <Input.TextArea
            value={invokeParam?.requestBodyOption?.requestBody}
            onChange={(e) => setInvokeParam({
              ...invokeParam,
              requestBodyOption:{
                requestBody: e.target.value,
                bodyType: invokeParam?.requestBodyOption?.bodyType,
                requestBodyType: invokeParam?.requestBodyOption?.requestBodyType
              }
            })}
            placeholder="Controlled autosize"
            autoSize={{ minRows: 6, maxRows: 8 }}
          />
        }
      </>),
    },
  ];

  return (
    <PageContainer title={false} breadcrumbRender={false}>
      <Row>
        <Col span={18}>
          <Space.Compact size="large" block={true}>
            <Select
              defaultValue="POST"
              options={requestMethodOptions}
              value={invokeParam?.method}
              onChange={(value) =>
                setInvokeParam({
                  ...invokeParam,
                  method: value,
                })
              }
            />
            <Input
              defaultValue=""
              value={invokeParam.url}
              onChange={(e) =>
                setInvokeParam({
                  ...invokeParam,
                  url: e.target.value,
                })
              }
            />
          </Space.Compact>
        </Col>
        <Col span={3}>
          <Dropdown.Button
            type={'primary'}
            size={'large'}
            icon={<DownOutlined />}
            onClick={sendRequest}
            menu={{ items:interfaceInfoList, onClick: onMenuClick }}
          >
            发送
          </Dropdown.Button>
        </Col>

      </Row>
      <Tabs defaultActiveKey="1" items={tabItems} onChange={onTabChange} />

      <Divider />
      <ProCard
        title='Response'
        boxShadow
      >
        <div>{baseResponse}</div>
      </ProCard>

      <InterfaceInfoDrawer
        currentInterfaceDetail={currentInterfaceDetail}
        openDrawer={openDrawer}
        closeDrawer={()=>setOpenDrawer(false)}
      />
    </PageContainer>
  );
};

export default App;
